﻿using DimensionsHelper.LanguageService.Symbols;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public abstract class AnalysisExpression(AnalysisBoundKinds kind, Expression syntaxNode, AnalysisNode? parent) :
    AnalysisNode(kind, syntaxNode, parent)
{
    public override bool IsExpression => true;

    public override bool IsStatement => false;

    public override bool IsMetadata => false;

    public override int ChildrenCount => 0;

    public override Expression Syntax => syntaxNode;


    /// <summary>
    ///     如果节点是标识符，此属性是<see langword="true" />。
    /// </summary>
    public bool IsIdentifier => Syntax.IsNode(SyntaxKinds.Identifier);


    /// <summary>
    ///     如果节点是常量表达式节点，此属性是<see langword="true" />。
    /// </summary>
    public bool IsLiteral => SyntaxFacts.IsLiteralKind(Syntax.Kind);


    /// <summary>
    ///     如果节点是字符串常量节点，此属性是<see langword="true" />。
    /// </summary>
    public bool IsString => Syntax.IsNode(SyntaxKinds.String);


    /// <summary>
    ///     如果节点是数字常量节点，此属性是<see langword="true" />。
    /// </summary>
    public bool IsNumber => Syntax.IsOneOfNode(SyntaxKinds.Integer, SyntaxKinds.Double);


    /// <summary>
    ///     如果节点是整数常量，此属性是<see langword="true" />。
    /// </summary>
    public bool IsLong => Syntax.IsNode(SyntaxKinds.Integer);


    /// <summary>
    ///     如果节点是浮点数常量，此属性是<see langword="true" />。
    /// </summary>
    public bool IsDouble => Syntax.IsNode(SyntaxKinds.Double);


    /// <summary>
    ///     如果节点是布尔常量节点，此属性是<see langword="true" />。
    /// </summary>
    public bool IsBoolean => Syntax.IsNode(SyntaxKinds.Boolean);


    /// <summary>
    ///     如果节点是分类常量节点，此属性是<see langword="true" />。
    /// </summary>
    public bool IsCategorical => Syntax.IsNode(SyntaxKinds.Categorical);


    /// <summary>
    ///     如果是空表达式，此属性是<see langword="true" />。
    /// </summary>
    public virtual bool IsEmpty => false;


    /// <summary>
    ///     将当前表达式转换为目标值类型表达式。
    /// </summary>
    /// <param name="targetType">目标值类型</param>
    /// <returns>如果转换失败，返回<see langword="null" /></returns>
    public virtual AnalysisExpression? WithImplicitlyConversion(ValueTypeSymbol targetType)
    {
        return null;
    }
}